
/*

<OWNER> = Deborah Kimnach
<YEAR> = 2009-2010

Copyright (c) <YEAR>, <OWNER>
All rights reserved.

Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions are met:

* Redistributions of source code must retain the above copyright notice,
  this list of conditions and the following disclaimer.

* Redistributions in binary form must reproduce the above copyright notice,
  this list of conditions and the following disclaimer in the documentation
  and/or other materials provided with the distribution.

* Neither the name of the <OWNER> nor the names of its contributors may
  be used to endorse or promote products derived from this software without
  specific prior written permission.

THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED.

IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE FOR ANY
DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
(INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

*/

package com.cc_toolbox;

import android.app.Activity;
import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.Intent;
import android.graphics.Color;
import android.graphics.drawable.PaintDrawable;
import android.os.Bundle;
import android.view.ContextMenu;
import android.view.ContextMenu.ContextMenuInfo;
import android.view.Menu;
import android.view.MenuInflater;
import android.view.MenuItem;
import android.view.View;
import android.view.View.OnClickListener;
import android.view.View.OnFocusChangeListener;
import android.widget.AbsoluteLayout;
import android.widget.Button;
import android.widget.EditText;
import android.widget.LinearLayout;
import android.widget.TextView;
import android.widget.Toast;
import java.util.ArrayList;
import com.cc_toolbox.initiative.Dealer;
import com.cc_toolbox.player.Player;
import java.util.HashMap;

/**
 *
 * @author Deborah Kimnach
 */
public class MainActivity extends Activity implements OnClickListener, OnFocusChangeListener {

    private Dealer dealer;// = new Dealer();

    // indicator if we should (re)create player 'deck'
    private boolean dealt = false;
    
    private EditText view; // needed for context menu

    // labels and textboxes
    private TextView lbl_turn1;
    private TextView lbl_turn2;
    private TextView lbl_turn3;
    private TextView lbl_turn4;
    private TextView lbl_turn5;
    private TextView lbl_turn6;
    private TextView lbl_count;

    private EditText turn1;
    private EditText turn2;
    private EditText turn3;
    private EditText turn4;
    private EditText turn5;
    private EditText turn6;

    private Button btnDeal;
    private AbsoluteLayout count;
    private LinearLayout pane;
    private LinearLayout pane1;
    private LinearLayout pane2;
    private LinearLayout pane3;
    private LinearLayout pane4;
    private LinearLayout pane5;
    private LinearLayout pane6;
    private HashMap<Integer, String> items; // Plan 'B' choices for context dialog menu
    
    private int[] ids;
    private EditText[] texts;
    private TextView[] labels;
    private int[] colors;
    private LinearLayout[] panes;

    /** Called when the activity is first created. */
    @SuppressWarnings("deprecation")
	@Override
    public void onCreate(Bundle icicle) {
        super.onCreate(icicle);

        setContentView(R.layout.main_layout);
        lbl_turn1 = (TextView)findViewById(R.id.lbl_turn1);
        lbl_turn2 = (TextView)findViewById(R.id.lbl_turn2);
        lbl_turn3 = (TextView)findViewById(R.id.lbl_turn3);
        lbl_turn4 = (TextView)findViewById(R.id.lbl_turn4);
        lbl_turn5 = (TextView)findViewById(R.id.lbl_turn5);
        lbl_turn6 = (TextView)findViewById(R.id.lbl_turn6);
        lbl_count = (TextView)findViewById(R.id.lbl_count);

        turn1 = (EditText)findViewById(R.id.turn1);
        turn2 = (EditText)findViewById(R.id.turn2);
        turn3 = (EditText)findViewById(R.id.turn3);
        turn4 = (EditText)findViewById(R.id.turn4);
        turn5 = (EditText)findViewById(R.id.turn5);
        turn6 = (EditText)findViewById(R.id.turn6);
        
        btnDeal = (Button)findViewById(R.id.btnDeal);
        count = (AbsoluteLayout)findViewById(R.id.countLayout);
        pane = (LinearLayout)findViewById(R.id.mainLayout);
        pane1 = (LinearLayout)pane.findViewById(R.id.turn1_layout);
        pane2 = (LinearLayout)pane.findViewById(R.id.turn2_layout);
        pane3 = (LinearLayout)pane.findViewById(R.id.turn3_layout);
        pane4 = (LinearLayout)pane.findViewById(R.id.turn4_layout);
        pane5 = (LinearLayout)pane.findViewById(R.id.turn5_layout);
        pane6 = (LinearLayout)pane.findViewById(R.id.turn6_layout);

        // for easy looping on create deck and deal
        // but need to continuously sync with real vars because these are not refs!
        panes  = new LinearLayout[] { pane1, pane2, pane3, pane4, pane5, pane6 };
        texts  = new EditText[] { turn1, turn2, turn3, turn4, turn5, turn6 };
        labels = new TextView[] { lbl_turn1, lbl_turn2, lbl_turn3, lbl_turn4, lbl_turn5, lbl_turn6 };
        ids    = new int[] { R.id.turn1, R.id.turn2, R.id.turn3, R.id.turn4, R.id.turn5, R.id.turn6 };
        colors = new int[] { Color.RED, Color.YELLOW, Color.LTGRAY, Color.GREEN, Color.MAGENTA, Color.CYAN};

        // listeners
        btnDeal.setOnClickListener(this);
        /*turn1.setOnFocusChangeListener(this);
        turn2.setOnFocusChangeListener(this);
        turn3.setOnFocusChangeListener(this);
        turn4.setOnFocusChangeListener(this);
        turn5.setOnFocusChangeListener(this);
        turn6.setOnFocusChangeListener(this);
        */
    }

    public void onClick(View v) {
        deal();
    }

    public void onFocusChange(View v, boolean focused) {
        // we only want to recreate the deck if a name is changed
        if (v.isEnabled()) {
            dealt = false;
        }
    }

    @Override
    public boolean onCreateOptionsMenu(Menu menu) {
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.main_menu, menu);

        return true;
    }

    @Override
    public boolean onOptionsItemSelected(MenuItem item) {
        boolean win = super.onOptionsItemSelected(item);
        
        int id = item.getItemId();
        if (id == R.id.menuNew) {
            newGame();
            
        } else if (id == R.id.menuReset) {
            resetGame(); // resets counter, doesn't clear names

        } else if (id == R.id.menuHelp) {
        	showHelp();

        } else if (id == R.id.menuDeal) { // id = menuDeal
            deal();
            
        }

        return win;
    }

    @Override
    public void onCreateContextMenu(ContextMenu menu, View v, ContextMenuInfo menuInfo) {
        //super.onCreateContextMenu(menu, v, menuInfo);

        EditText et = (EditText)v;
        // Setup the menu header
        menu.setHeaderTitle(et.getText().toString() + "...");
        MenuInflater inflater = getMenuInflater();
        inflater.inflate(R.menu.context_menu, menu);
        view = (EditText)v;
    }

    @Override
    public boolean onContextItemSelected(MenuItem item) {
        switch (item.getItemId()) {
            case R.id.planB:
                planB(view);
                view = null;
                break;
            case R.id.killPlayer:
                killPlayer(view);
                view = null;
                break;
            case R.id.toFirst:
                toFirst(view);
                view = null;
                break;
            case R.id.toLast:
                toLast(view);
                view = null;
                break;
            default:
                break;
        }
        return super.onContextItemSelected(item);
    }

    // compile deck of current players
    private void createDeck() throws Exception {
        ArrayList<Player> players = new ArrayList<Player>();
        
        
        for (int i = 0; i < texts.length; i++) {
        	EditText text = texts[i];
        	int color = colors[i];
        	
        	if (pane.findViewById(ids[i]) != null && !(text.getText().toString().equals(""))) {
            	Player p = new Player(text.getText().toString(), color);
            	players.add(p);
            	registerForContextMenu(text);
                texts[i].setBackgroundColor(color);
            	labels[i].setText((i+1) + ": ");
            }
        }
        
        System.out.print(players.size());
        
        if (players.size() > 2) {
            dealer = new Dealer(players);
            lbl_count.setText(dealer.getDealCounter().toString());
        } else {
            throw new Exception("Not enough players");
        }
    }

    private void toFirst (EditText p) {
        int i = indexOfPlayer(p);

        if (i != -1 && i < 6) {
            popToast(p.getText().toString() + " is now last");
            dealer.moveToTop(i);
            refresh();
        }

    }

    private void toLast (EditText p) {
        int i = indexOfPlayer(p);

        if (i != -1 && i < 6) {
            popToast(p.getText().toString() + " is now last");
            dealer.moveToBottom(i);
            refresh();
        }
    }

    private void killPlayer(EditText p) {
        int i = indexOfPlayer(p);

        if (i != -1 && i < 6) {
            popToast(p.getText().toString() + " dies");
            dealer.killPlayer(i);
            refresh();
        }        
    }

    // deal new initiatives
    private void deal() {
        try {
            if (!dealt) {
                createDeck();
            }

            dealer.deal();

            refresh();
            dealt = true;
            
        } catch (Exception e) {
            e.printStackTrace();
            //popToast("Must have at least 3 player to deal");
            popToast(e.getMessage());
        }
    }

    // player selects plan B
    private void planB(final EditText thisone) {
        // build list of eligible players to switch with
        items = new HashMap<Integer, String>();
        int index = 0; // index in deck NOT dialog box

        if (pane.findViewById(R.id.turn1) != null && thisone != turn1 && turn1.isEnabled()
                && !turn1.getText().toString().equals(""))
        {
            System.out.println(index + ", " + turn1.getText().toString());
            items.put(index, turn1.getText().toString());
        }
        if (pane.findViewById(R.id.turn1) != null) { index++; }
        
        if (pane.findViewById(R.id.turn2) != null && thisone != turn2 && turn2.isEnabled() 
                && !turn2.getText().toString().equals(""))
        {
            System.out.println(index + ", " + turn2.getText().toString());
            items.put(index, turn2.getText().toString());
        }
        if (pane.findViewById(R.id.turn2) != null) { index++; }

        if (pane.findViewById(R.id.turn3) != null && thisone != turn3 && turn3.isEnabled() 
                && !turn3.getText().toString().equals(""))
        {
            System.out.println(index + ", " + turn3.getText().toString());
            items.put(index, turn3.getText().toString());
        }
        if (pane.findViewById(R.id.turn3) != null) { index++; }

        if (pane.findViewById(R.id.turn4) != null && thisone != turn4 && turn4.isEnabled() 
                && !turn4.getText().toString().equals(""))
        {
            System.out.println(index + ", " + turn4.getText().toString());
            items.put(index, turn4.getText().toString());
        }
        if (pane.findViewById(R.id.turn4) != null) { index++; }

        if (pane.findViewById(R.id.turn5) != null && thisone != turn5 && turn5.isEnabled() 
                && !turn5.getText().toString().equals(""))
        {
            System.out.println(index + ", " + turn5.getText().toString());
            items.put(index, turn5.getText().toString());
        }
        if (pane.findViewById(R.id.turn5) != null) { index++; }

        if (pane.findViewById(R.id.turn6) != null && thisone != turn6 && turn6.isEnabled() 
                && !turn6.getText().toString().equals(""))
        {
            System.out.println(index + ", " + turn6.getText().toString());
            items.put(index, turn6.getText().toString());
        }
        
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle("Switch " + thisone.getText().toString() + " with ...");
        String[] tmp = items.values().toArray(new String[items.values().size()]);
        builder.setItems(tmp, new DialogInterface.OnClickListener() {
            public void onClick(DialogInterface dialog, int thatone) {
                planB(thisone, thatone);
                dialog.dismiss();
                refresh();
            }
        });
        
        AlertDialog alert = builder.create();
        alert.show();
    }

    // user has selected players to swap
    private void planB(EditText thisone, int thatone) {
        int one = -1;
        int two = -1;
        boolean found = false;

        one = indexOfPlayer(thisone);
        two = (Integer)items.keySet().toArray()[thatone];

        // only switch if user has selected an option
        if ((one != -1 && two != -1 && one < 6 && two < 6) && (one != two)) {
            popToast("Players " + thisone.getText().toString() + " & " + items.get(thatone) + " switched ");
            dealer.swap(one, two);
            refresh();
        } else {
            System.out.println(thisone.getText().toString() + ": " + one + ", " + two);
        }
    }

    // refresh textboxes from arraylist
    private void refresh() {
        ArrayList<Player> players = dealer.getList();
        
        for (int i = 0; i < texts.length; i++) {
        	EditText text  = texts[i];
        	TextView label = labels[i];
        	
        	if (i < players.size()) {
        		text.setText(players.get(i).getName());
        		text.setBackgroundColor(players.get(i).getColor());
				text.setEnabled(!players.get(i).isDead());
				label.setText((i+1) + ": ");
		        registerForContextMenu(text);
        	}
        	else {
        		text.setText("");
	        	label.setText("");
	        	if (pane.findViewById(ids[i]) != null) {
	        		panes[i].removeView(text);
	        		panes[i].removeView(label);
        		}
	        	unregisterForContextMenu(text);
	        	
        	}
        }
        
        lbl_count.setText(dealer.getDealCounter().toString());
    }

    // reset textboxes for new game
    private void newGame() {
        System.out.println("New Game");
        
        for (int i = 0; i < 6; i++) {
        	EditText text = texts[i];
        	
        	text.setBackgroundColor(colors[i]);
        	text.setEnabled(true);
            text.setText("");
            labels[i].setText((i+1) + ": ");
            unregisterForContextMenu(text);

        	if (panes[i].findViewById(ids[i]) == null) {
        		panes[i].addView(labels[i]);
        		panes[i].addView(text);        		
        	}
        }

        dealer.newGame();
        lbl_count.setText(dealer.getDealCounter().toString());
        dealt = false;
    }

    private void resetGame() {
        System.out.println("Reset Game");
        
        for (int i = 0; i < 6; i++) {
        	EditText text = texts[i];
        	
        	text.setEnabled(true);
        	unregisterForContextMenu(text);
        }
        
        dealer.newGame();
        lbl_count.setText(dealer.getDealCounter().toString());
        dealt = false;
    }

    // pop a Toast
    public void popToast(String msg) {
        Context context = getApplicationContext();
        CharSequence text = msg;
        int duration = Toast.LENGTH_LONG;

        Toast toast = Toast.makeText(context, text, duration);
        toast.show();
    }

    private void showAbout() {
        AlertDialog.Builder builder = new AlertDialog.Builder(this);
        builder.setTitle(R.string.main_title);

        TextView ver = (TextView) findViewById(R.id.ver);
        ver.setText(R.string.ver);

        TextView copy = (TextView) findViewById(R.id.copy);
        copy.setText(R.string.copy);

        TextView dev = (TextView) findViewById(R.id.dev);
        dev.setText(R.string.dev);

        builder.setMessage(ver.getText().toString() + "\n" + copy.getText().toString() + "\n" + dev.getText().toString());

        AlertDialog alert = builder.create();
        alert.show();
    }

    private void showHelp() {
        this.startActivity(new Intent(this.getApplicationContext(), HelpActivity.class));
    }

    private int indexOfPlayer(EditText player) {
        int index = -1;
        boolean found = false;

        if (player == turn1) {
            index++;
            found = true;
        } else {
            if (!found && pane.findViewById(R.id.turn1) != null) { index++; }
        }

        if(player == turn2) {
            index++;
            found = true;
        } else {
            if (!found && pane.findViewById(R.id.turn2) != null) { index++; }
        }

        if(player == turn3) {
            index++;
            found = true;
        } else {
            if (!found && pane.findViewById(R.id.turn3) != null) { index++; }
        }

        if(player == turn4) {
            index++;
            found = true;
        } else {
            if (!found && pane.findViewById(R.id.turn4) != null) { index++; }
        }

        if(player == turn5) {
            index++;
            found = true;
        } else {
            if (!found && pane.findViewById(R.id.turn5) != null) { index++; }
        }

        if (player == turn6) {
            index++;
            found = true;
        } else {
            if (!found && pane.findViewById(R.id.turn6) != null) { index++; }
        }

        return index;
    }
}